/*
 * $Id: ScopedPtr.h,v 1.1 2006-02-09 04:38:53 bacon Exp $
 */

#ifndef _XPP_SCOPEDPTR_CLASS_
#define _XPP_SCOPEDPTR_CLASS_

#include <xpp/Uncopyable.h>
#include <xp/bas/assert.h>

namespace xpp
{

	class ScopedPtrType 
	{
	public:
		enum Value {
			SINGLETON = 0,
			ARRAY     = 1
		};	
	};
	
	template<class T, ScopedPtrType::Value type = ScopedPtrType::SINGLETON>
	class ScopedPtr: public Uncopyable
	{
	public:
		ScopedPtr (T* p = (T*)XP_NULL) 
		{
			_ptr = p;
		}
	
		~ScopedPtr () 
		{
			if (_ptr != XP_NULL) {
				if (type == ScopedPtrType::SINGLETON) delete _ptr;
				else delete[] _ptr;
			}
		}
		
		T& operator* () const 
		{
			xp_assert (_ptr != (T*)XP_NULL);
			return *_ptr;
		}
		T* operator-> () const 
		{
			xp_assert (_ptr != (T*)XP_NULL);
			return _ptr;	
		}
	
		int operator! () const 
		{
			return _ptr == (T*)XP_NULL;
		}
	
		T& operator[] (xp_size_t idx) 
		{
			xp_assert (_ptr != (T*)XP_NULL);
			return _ptr[idx];
		}
	
		T* get () 
		{
			return _ptr;
		}
	
		T* release () 
		{
			T* t = _ptr;
			_ptr = (T*)XP_NULL;
			return t;
		}
	
		void reset (T* p = (T*)XP_NULL) 
		{
			if (_ptr) {
				if (type == ScopedPtrType::SINGLETON) delete _ptr;
				else delete[] _ptr;
			}

			_ptr = p;
		}
	
	protected:
		T* _ptr;
	}; 

}
#endif
